/**
 * @file wa_imgbtn.c
 *
 */

 /*********************
 *      INCLUDES
 *********************/
#include "wa_conf.h"
#if USE_WA_IMGBTN != 0
#include "wa_imgbtn.h"

 /*********************
 *      DEFINES
 *********************/

 /**********************
 *      TYPEDEFS
 **********************/

 /**********************
 *  STATIC PROTOTYPES
 **********************/
static wa_obj_callback ancestor_callback;
static void wa_imgbtn_callback(wa_sign* sign);
/**********************
 *  STATIC VARIABLES
 **********************/


 /**********************
 *      MACROS
 **********************/

 /**********************
 *   GLOBAL FUNCTIONS
 **********************/
 /**
 * imgbtn module init
 */
void wa_imgbtn_module_init(void)
{
}

/**
* create a imgbtn
* @param par
* @return imgbtn obj
*/
wa_obj* wa_imgbtn_create(wa_obj* par)
{
	wa_obj* new_imgbtn;
	wa_imgbtn_ext* imgbtn_ext;

	new_imgbtn = wa_obj_create(par, NULL);
	if (new_imgbtn == NULL)
	{
		return new_imgbtn;
	}

	if (ancestor_callback == NULL)
	{
		ancestor_callback = wa_obj_get_callback(new_imgbtn);
	}
	imgbtn_ext = wa_obj_malloc_ext_attr(new_imgbtn, sizeof(imgbtn_ext));
	if (imgbtn_ext == NULL)
	{
		return NULL;
	}

	imgbtn_ext->bitmap = NULL;
	imgbtn_ext->fore_color = WA_COLOR_FOREGROUND;
	imgbtn_ext->back_color = WA_COLOR_BACKGROUND;
	imgbtn_ext->state = WA_IMGBTN_STATE_UNPRESSED;
	imgbtn_ext->press_offset = 0;
	imgbtn_ext->offset_dir = WA_IMGBTN_PRESS_OFFSET_RIGHT;

	wa_obj_set_callback(new_imgbtn, wa_imgbtn_callback);

	return new_imgbtn;
}

/**
* imgbtn set bitmap
* @param imgbtn
* @param bitmap
*/
void wa_imgbtn_set_bitmap(wa_obj* imgbtn, wa_bitmap* bitmap)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	ext->bitmap = bitmap;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn set fore color
* @param imgbtn
* @param fore color
*/
void wa_img_set_fore_color(wa_obj* imgbtn, wa_gui_color fore_color)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	ext->fore_color = fore_color;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn set back color
* @param imgbtn
* @param back color
*/
void wa_imgbtn_set_back_color(wa_obj* imgbtn, wa_gui_color back_color)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	ext->back_color = back_color;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn set state
* @param imgbtn
* @param state
*/
void wa_imgbtn_set_state(wa_obj* imgbtn, wa_imgbtn_state state)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	if (ext->state == state)
	{
		return;
	}
	if (state == WA_IMGBTN_STATE_DISABLED)
	{
		ext->state = state;
		imgbtn->flag &= ~WA_CF_ENABLE;
	}
	if ((ext->state == WA_IMGBTN_STATE_DISABLED) && (state != WA_IMGBTN_STATE_DISABLED))
	{
		imgbtn->flag |= WA_CF_ENABLE;
	}
	if (state == WA_IMGBTN_STATE_PRESSED)
	{
		ext->state = state;
		wa_wm_notify_parent(imgbtn, WA_SIGNAL_NOTIFY_PRESSED);
	}
	if ((ext->state == WA_IMGBTN_STATE_PRESSED) && (state != WA_IMGBTN_STATE_PRESSED))
	{
		ext->state = state;
		wa_wm_notify_parent(imgbtn, WA_SIGNAL_NOTIFY_RELEASED);
	}
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn set press offset
* @param imgbtn
* @param press offset
*/
void wa_imgbtn_set_press_offset(wa_obj* imgbtn, uint32_t press_offset)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	ext->press_offset = press_offset;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn set offset dir
* @param imgbtn
* @param offset dir
*/
void wa_imgbtn_set_offset_dir(wa_obj* imgbtn, wa_imgbtn_press_offset_dir offset_dir)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	ext->offset_dir = offset_dir;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn enable
* @param imgbtn
*/
void wa_imgbtn_enable(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	imgbtn->flag |= WA_CF_ENABLE;
	ext->state = WA_IMGBTN_STATE_UNPRESSED;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn disable
* @param imgbtn
*/
void wa_imgbtn_disable(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	imgbtn->flag &= ~WA_CF_ENABLE;
	ext->state = WA_IMGBTN_STATE_DISABLED;
	wa_obj_invalidate(imgbtn);
}

/**
* imgbtn get bitmap
* @param imgbtn
* @return bitmap
*/
wa_bitmap* wa_imgbtn_get_bitmap(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->bitmap;
}

/**
* imgbtn get fore color
* @param imgbtn
* @return fore color
*/
wa_gui_color wa_imgbtn_get_fore_color(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->fore_color;
}

/**
* imgbtn get back color
* @param imgbtn
* @return back color
*/
wa_gui_color wa_imgbtn_get_back_color(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->back_color;
}

/**
* imgbtn get state
* @param imgbtn
* @return state
*/
wa_imgbtn_state wa_imgbtn_get_state(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->state;
}

/**
* imgbtn get press offset
* @param imgbtn
* @return press offset
*/
uint32_t wa_imgbtn_get_press_offset(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->press_offset;
}

/**
* imgbtn get offset dir
* @param imgbtn
* @return offset dir
*/
wa_imgbtn_press_offset_dir wa_imgbtn_get_offset_dir(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	return ext->offset_dir;
}

/**
* imgbtn is pressed
* @param imgbtn
* @return is pressed
*/
wa_result wa_imgbtn_is_pressed(wa_obj* imgbtn)
{
	wa_imgbtn_ext* ext;
	ext = wa_obj_get_ext_attr(imgbtn);
	if (ext->state == WA_IMGBTN_STATE_PRESSED)
	{
		return wa_ok;
	}
	return wa_nok;
}

/**********************
*   STATIC FUNCTIONS
**********************/
/**
* img redraw functions
* @param obj
*/
static void _Paint(wa_obj* obj)
{
	wa_imgbtn_ext* ext;
	int w, h;
	ext = wa_obj_get_ext_attr(obj);
	w = wa_obj_get_width(obj);
	h = wa_obj_get_height(obj);
	if (ext->bitmap == NULL)
	{
		return;
	}
	wa_mask_fillrect(obj->rect.x1, obj->rect.y1, w, h, &(obj->redraw_rect), ext->back_color);
	if (ext->state == WA_IMGBTN_STATE_PRESSED)
	{
		int relx, rely;
		if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_UP)
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1;
			h -= ext->press_offset;
		}
		else if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_DOWN)
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1 + ext->press_offset;
			h -= ext->press_offset;
		}
		else if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_LEFT)
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1;
			w -= ext->press_offset;
		}
		else
		{
			relx = obj->rect.x1 + ext->press_offset;
			rely = obj->rect.y1;
			w -= ext->press_offset;
		}
		wa_mask_fillrect(relx, rely, w, h, &(obj->redraw_rect), ext->fore_color);
		wa_mask_draw_bitmap(relx, rely, ext->bitmap, &(obj->redraw_rect), ext->back_color);
	}
	else
	{
		int relx, rely;
		if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_UP)
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1 + ext->press_offset;
		}
		else if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_DOWN)
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1;
		}
		else if (ext->offset_dir == WA_IMGBTN_PRESS_OFFSET_LEFT)
		{
			relx = obj->rect.x1 + ext->press_offset;
			rely = obj->rect.y1;
		}
		else
		{
			relx = obj->rect.x1;
			rely = obj->rect.y1;
		}
		wa_mask_draw_bitmap(relx, rely, ext->bitmap, &(obj->redraw_rect), ext->fore_color);
	}
}

/**
 * img obj delete function
 * @param obj
 */
static void _Delete(wa_obj* obj)
{
}

/**
 * imgbtn obj callback function
 * @param sign
 */
static void wa_imgbtn_callback(wa_sign* sign)
{
	int sign_id;
	wa_obj* obj;

	ancestor_callback(sign);
	sign_id = sign->sign_id;
	obj = sign->obj_dst;

	switch (sign_id)
	{
		case WA_SIGNAL_PAINT:
		{
			_Paint(obj);
			break;
		}
		case WA_SIGNAL_DELETE:
		{
			_Delete(obj);
			break;
		}
		case WA_SIGNAL_PRESSED:
		{
			wa_imgbtn_ext* ext;
			ext = wa_obj_get_ext_attr(obj);
			ext->state = WA_IMGBTN_STATE_PRESSED;
			wa_wm_notify_parent(obj, WA_SIGNAL_NOTIFY_PRESSED);
			wa_obj_invalidate(obj);
			break;
		}
		case WA_SIGNAL_PRESS_LOST:
		{
			wa_imgbtn_ext* ext;
			ext = wa_obj_get_ext_attr(obj);
			ext->state = WA_IMGBTN_STATE_UNPRESSED;
			wa_wm_notify_parent(obj, WA_SIGNAL_NOTIFY_PRESS_LOST);
			wa_obj_invalidate(obj);
			break;
		}
		case WA_SIGNAL_RELEASED:
		{
			wa_imgbtn_ext* ext;
			ext = wa_obj_get_ext_attr(obj);
			ext->state = WA_IMGBTN_STATE_UNPRESSED;
			wa_wm_notify_parent(obj, WA_SIGNAL_NOTIFY_RELEASED);
			wa_obj_invalidate(obj);
			break;
		}
		default:
		{
			break;
		}
	}
}

#endif
